package cn.s1995.sloth.common.core.i18n;

import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;

/**
 * WebMvcConfig
 *
 * @author Lex
 * @description 国际化配置
 * <pre>
 *     如果在 Spring 的 MessageSource 中设置了默认语言环境：
 *      当请求的语言环境没有对应的资源文件时，系统通常会首先尝试回退到更通用的语言环境，如果这也失败了，才会使用设置的默认语言环境。
 *
 * 例如：
 *      如果请求的是 zh_TW 但没有找到对应的 message_zh_TW.properties 文件，Spring 会首先检查是否有 message_zh.properties 文件（更通用的中文资源）。
 *      如果 message_zh.properties 也不存在，Spring 则会使用在 MessageSource 中配置的默认语言环境对应的资源文件。
 *
 * 这意味着，设置默认语言环境并不会阻止 Spring 尝试找到更通用的语言环境，它只是确保在所有其他选项都不可用时，有一个后备选项。
 * 这个机制确保了即使在缺少特定语言的资源文件时，应用程序也能够正常工作，只是显示的是默认语言的内容。
 * </pre>
 * @date 2023/12/09 15:17
 */
@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
public class I18nConfig implements WebMvcConfigurer {

    /**
     * 语言参数
     */
    public static final String LANGUAGE = "Language";

    /**
     * 本地化解析器：
     *      默认情况下，SpringMVC 根据 Accept-Language 参数判断客户端的本地化类型。
     *      当接受到请求时，SpringMVC 会在上下文中查找一个本地化解析器（LocalResolver），找到后使用它获取请求所对应的本地化类型信息。
     *      SpringMVC 还允许装配一个动态更改本地化类型的拦截器，这样通过指定一个请求参数就可以控制单个请求的本地化类型：
     *          AcceptHeaderLocaleResolver：根据 HTTP 请求头的 Accept-Language 参数确定本地化类型，如果没有显式定义本地化解析器， SpringMVC 使用该解析器。
     *          CookieLocaleResolver：根据指定的 Cookie 值确定本地化类型
     *          SessionLocaleResolver：根据 Session 中特定的属性确定本地化类型
     *          LocaleChangeInterceptor：从请求参数中获取本次请求对应的本地化类型。
     *          实现 LocaleResolver 接口，自定义本地化解析器
     * @return
     */
    @Bean
    public LocaleResolver localeResolver() {
        // return new I18nCookieLocaleResolver();
        return new I18nCustomLocaleResolver();
    }

    /**
     * 配置拦截器获取请求中的语言参数
     * @return
     */
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor i18nInterceptor = new LocaleChangeInterceptor();
        // 设置请求参数名，默认为locale
        i18nInterceptor.setParamName(LANGUAGE);

        return i18nInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        // 注册拦截器到容器中
        registry.addInterceptor(localeChangeInterceptor());
    }


}
